package com.web.kdl.service.flywheel;

import cn.hutool.core.date.DateTime;
import cn.hutool.db.meta.Table;
import com.web.kdl.daoV2.flyWheel.FlyWheelDao;
import com.web.kdl.daoV2.matrix.MatrixDao;
import com.web.kdl.daoV2.siteWheel.SiteWheelDao;
import com.web.kdl.entity.flywheelDataAnalysis.FlywheelDataAnalysis;
import com.web.kdl.entity.maDataReport.DataReport;
import com.web.kdl.entity.matrix.Matrix;
import com.web.kdl.pojo.Vo.DailyPowerAvgVo;
import com.web.kdl.pojo.Vo.EnergyDataVo;
import com.web.kdl.pojo.Vo.FlyWheelData;
import com.web.kdl.pojo.Vo.FlywheelInfoVo;
import com.web.kdl.pojo.Vo.RT.RtDataVo;
import com.web.kdl.pojo.Vo.flywheel.FlyWheelEleCountVo;
import com.web.kdl.pojo.Vo.flywheel.FlywheelAlertInfoVo;
import com.web.kdl.pojo.Vo.flywheel.FlywheelMainInfoVo;
import com.web.kdl.pojo.Vo.flywheel.FlywheelVo;
import com.web.kdl.pojo.dto.FlywheelInfoDTo;
import com.web.kdl.pojo.dto.FlywheelMainDto;
import com.web.kdl.pojo.dto.SiteDto;
import com.web.kdl.pojo.dto.TableDto;
import com.web.kdl.pojo.form.FlywheelForm;
import com.web.kdl.service.createTable.FlywheelTable;
import com.web.kdl.service.createTable.TableDataType;
import com.web.kdl.service.createTable.TableType;
import com.web.kdl.service.createTable.factory.TableFactory;
import com.web.kdl.util.RedisKeyUtil;
import com.web.kdl.util.RedisUtils;
import com.web.kdl.util.TableNameUtils;
import org.apache.poi.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Author： shulibin
 * @Date： 2025/7/24 8:59
 * @Describe：
 */
@Service
public class FlyWheelServiceImpl implements FlyWheelService{
    @Resource
    private FlyWheelDao flyWheelDao;
    @Resource
    private SiteWheelDao siteWheelDao;

    @Autowired
    private TableFactory tableFactory;
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Resource
    RedisUtils  redisUtils;
    @Resource
    MatrixDao  matrixDao;
    // finish
    @Override
    public List<Map<String, Object>> getFlywheelDayAverageSoc(FlywheelForm form) {
        String dataTable = TableNameUtils.getDataTableName(form.getSiteName(),form.getMatrixName(),form.getTableNum(), TableDataType.DAY);
        return flyWheelDao.selectAverageSocUsage(dataTable);
    }
    // finish
    @Override
    public List<FlyWheelEleCountVo> getFlywheelMonthCount(FlywheelForm form) {
        String dataTable = TableNameUtils.getDataTableName(form.getSiteName(),form.getMatrixName(),form.getTableNum(),TableDataType.DAY);
      return flyWheelDao.selectLastDayChargeDischargeStats(dataTable);
    }

    // finish
    @Override
    public  List<DailyPowerAvgVo>  getFlywheelDayAveragePower(FlywheelForm form) {
        String dataTable = TableNameUtils.getDataTableName(form.getSiteName(),form.getMatrixName(),form.getTableNum(),TableDataType.DAY);
        return flyWheelDao.selectDailyPowerAvg(dataTable);
    }
    // finish
    @Override
    public List<FlywheelAlertInfoVo> getFlywheelUnitInfo(FlywheelForm form) {
        String dataTable = TableNameUtils.getAlertTableName(form.getSiteName(),form.getMatrixName(),form.getTableNum());
        return flyWheelDao.selectFlywheelUnitInfo(dataTable);
    }

//    finish
    @Override
    public FlywheelMainInfoVo getFlywheelMainInfo(FlywheelForm form) {
        ArrayList<FlywheelMainDto> allResult = new ArrayList<>();
        String statusTable = TableNameUtils.getStatusTableName(form.getSiteName(),form.getMatrixName(),form.getTableNum());
        List<FlywheelMainDto> result1 = flyWheelDao.selectFlywheelMainInfo1(statusTable);
        allResult.addAll(result1);
        String dataTable = TableNameUtils.getDataTableName(form.getSiteName(),form.getMatrixName(),form.getTableNum(),TableDataType.DAY);
        List<FlywheelMainDto> result2 = flyWheelDao.selectFlywheelMainInfo2(dataTable);
        allResult.addAll(result2);
        return new FlywheelMainInfoVo(allResult);
    }

    @Override
    public List<EnergyDataVo> getAllFlywheelEleCount(List<String> tableList) {
        // 创建一个Map来存储合并后的结果，key是时间，value是合并后的EnergyData
        Map<String, EnergyDataVo> mergedData = new HashMap<>();
        // 合并四个列表的数据
        for (String table : tableList) {
            List<EnergyDataVo> wheel = flyWheelDao.selectFlywheelEleCount(table);
            mergeWheelData(mergedData,wheel);
        }
        // map 转list
        List<EnergyDataVo> result = new ArrayList<>(mergedData.values());
        // 按时间排序（如果需要）
        result.sort(Comparator.comparing(EnergyDataVo::getTime));
        return result;
    }

    @Override
    public List<EnergyDataVo> getAllFlywheelEleCount(String table) {
        // 创建一个Map来存储合并后的结果，key是时间，value是合并后的EnergyData
        Map<String, EnergyDataVo> mergedData = new HashMap<>();
            List<EnergyDataVo> wheel = flyWheelDao.selectFlywheelEleCount(table);
            mergeWheelData(mergedData,wheel);
        // map 转list
        List<EnergyDataVo> result = new ArrayList<>(mergedData.values());
        // 按时间排序（如果需要）
        result.sort(Comparator.comparing(EnergyDataVo::getTime));
        return result;
    }


    private void mergeWheelData(Map<String, EnergyDataVo> mergedData,
                                List<EnergyDataVo> wheelData) {
        for (EnergyDataVo data : wheelData) {
            String time = data.getTime();
            if (mergedData.containsKey(time)) {
                // 如果已有该月份数据，则累加充放电量
                EnergyDataVo existing = mergedData.get(time);
                existing.setCharge(existing.getCharge() + data.getCharge());
                existing.setDischarge(existing.getDischarge() + data.getDischarge());
            } else {
                // 如果没有该月份数据，则添加新记录
                mergedData.put(time, new EnergyDataVo(
                        time,
                        data.getCharge(),
                        data.getDischarge()
                ));
            }
        }
    }

    @Override
    public void createTable(String siteName, String matrixName,String flywheelName) {
        for (TableType type:TableType.values()){
            FlywheelTable table = tableFactory.createTable(siteName,matrixName, flywheelName, type);
            jdbcTemplate.execute(table.createTable());
        }
    }
    @Override
    public void deleteTable(String siteName,String matrixName, String flywheelName) {
        for (TableType type:TableType.values()){
            FlywheelTable table = tableFactory.deleteTable(siteName,matrixName,flywheelName, type);
            String s = table.deleteTable();
            jdbcTemplate.execute(s);
        }
    }

    @Override
    public ArrayList<RtDataVo> getAllProperty(TableDto siteDto) {
        ArrayList<RtDataVo> rtDataVos = new ArrayList<>();
        String dataTableName = TableNameUtils.getDataTableName(siteDto.getSiteName(),siteDto.getMatrixName(), siteDto.getFlywheelName());
        ArrayList<RtDataVo> dataProperty = flyWheelDao.selectDataProperty(dataTableName);
        rtDataVos.addAll(dataProperty);
        String statusTableName = TableNameUtils.getStatusTableName(siteDto.getSiteName(),siteDto.getMatrixName(), siteDto.getFlywheelName());
        ArrayList<RtDataVo> statusProperty = flyWheelDao.selectStatusProperty(statusTableName);
        rtDataVos.addAll(statusProperty);
        return rtDataVos;
    }

    @Override
    public  Map<String, FlyWheelData> getLastValue(FlywheelInfoDTo flywheelInfoDTo) {
        // 先从 redis 中获取 若不存在 在从 temp中获取
        Matrix matrix = matrixDao.selectByName(flywheelInfoDTo.getMatrixName());
        if(matrix == null){
            throw new RuntimeException("阵列不存在");
        }
        String redisKey = RedisKeyUtil.getRedisKey(matrix.getId(), flywheelInfoDTo.getFlyWheelName());
        List<FlywheelDataAnalysis> LastValueList = redisUtils.getMap(redisKey, FlywheelDataAnalysis.class);

        if (LastValueList != null && !LastValueList.isEmpty()) {
            Map<String, FlyWheelData> flyWheelDataMap = LastValueList.stream()
                    .collect(HashMap::new, (m, v) ->
                                    m.put(v.getDeviceName(), new FlyWheelData(v.getDeviceName(), String.format("%.2f", v.getDataValue()),  v.getUnit())),
                            HashMap::putAll);
            return flyWheelDataMap;
        }
        //redis不存在，查询数据库
        String tableName = TableNameUtils.getDataTableName(flywheelInfoDTo.getSumSite(),flywheelInfoDTo.getMatrixName(),
                flywheelInfoDTo.getFlyWheelName(),TableDataType.TEMP);
        List<DataReport> lastValue = flyWheelDao.getLastValue(tableName);
        Map<String, FlyWheelData> flyWheelDataMap = lastValue.stream()
                .collect(HashMap::new, (m, v) ->
                                m.put(v.getDeviceName(), new FlyWheelData(v.getDeviceName(), String.format("%.2f", v.getDataValue()), v.getUnit())),
                        HashMap::putAll);
        return flyWheelDataMap;
    }
}
